package otheri.download;

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.ArrayList;

import otheri.common.Utils;
import otheri.io.Input;
import otheri.io.Output;
import otheri.io.Serializable;
import android.app.Service;
import android.content.Context;
import android.content.Intent;
import android.os.Bundle;
import android.os.IBinder;

public class DownloadManager extends Service implements Serializable {

	public static final String SDCARD_ROOT = "/sdcard/otherdown/";

	public static final String FILE_ROOT = "/data/data/otheri.download/files/";

	public static final String TAG_CMD = "cmd";
	public static final String CMD_START_SERVICE = "startService";
	public static final String CMD_START_DOWNLOAD = "startDownload";

	public static final String PARAMETER_URL = "url";
	public static final String PARAMETER_FILE_NAME = "fileName";

	private static final String FILE_NAME_CONFIG = "config.cfg";

	private DownloadConfig config;
	private ArrayList<DownloadTask> tasks;

	@Override
	public void onCreate() {
		super.onCreate();

		this.tasks = new ArrayList<DownloadTask>();
		this.config = new DownloadConfig();

		// 每次服务创建时，读取配置文件。
		// 只有在配置更改时，需要将配置保存到本地
		this.writeConfig();
		readConfig();
	}

	@Override
	public void onStart(Intent intent, int startId) {
		super.onStart(intent, startId);

		Bundle bundle = intent.getExtras();
		String cmd = bundle.getString(TAG_CMD);
		if (cmd.equals(CMD_START_SERVICE)) {
			// 默认启动，没有做处理
		} else if (cmd.equals(CMD_START_DOWNLOAD)) {

			String url = bundle.getString(PARAMETER_URL);
			String fileName = bundle.getString(PARAMETER_FILE_NAME);

			Utils.println("startDownload @ " + url + " & " + fileName);

			// 启动一个下载任务
			DownloadTask downloadTask = new DownloadTask(this, url, fileName);
			tasks.add(downloadTask);
			new Thread(downloadTask).start();
		}
	}

	@Override
	public void onDestroy() {
		super.onDestroy();

		// 保存配置文件
		writeConfig();
	}

	@Override
	public IBinder onBind(Intent intent) {
		return null;
	}

	@Override
	public void onRebind(Intent intent) {
		super.onRebind(intent);
	}

	@Override
	public boolean onUnbind(Intent intent) {
		return super.onUnbind(intent);
	}

	/*
	 * 读取config
	 */
	private void readConfig() {
		try {
			InputStream is = openFileInput(FILE_NAME_CONFIG);
			Input in = new Input(is);
			config.deserialize(in);
			in.close();
			is.close();
		} catch (Exception e) {
			Utils.println("readConfig>" + e.toString());
		}
	}

	/*
	 * 写入config
	 */
	private void writeConfig() {
		try {
			OutputStream os = this.openFileOutput(FILE_NAME_CONFIG,
					Context.MODE_WORLD_WRITEABLE);
			Output out = new Output(os);
			config.serialize(out);
			out.close();
			os.close();
		} catch (Exception e) {
			Utils.println("writeConfig>" + e.toString());
			e.printStackTrace();
		}
	}

	public void serialize(Output out) throws IOException {
		out.writeInt(tasks.size());
		for (int i = 0; i < tasks.size(); i++) {
			DownloadTask dt = (DownloadTask) tasks.get(i);
			dt.serialize(out);
		}
	}

	public void deserialize(Input in) throws IOException {
		tasks.clear();
		int size = in.readInt();
		for (int i = 0; i < size; i++) {
			DownloadTask dt = new DownloadTask();
			dt.deserialize(in);
			tasks.add(dt);
		}
	}

	public DownloadConfig getConfig() {
		return config;
	}

	protected void saveTaskToFile(DownloadTask task, byte[] data)
			throws IOException {
		Utils.println("saveTaskToFile>" + SDCARD_ROOT + task.fileName);
		File file = new File(SDCARD_ROOT + task.fileName);
		FileOutputStream fos = new FileOutputStream(file);
		fos.write(data);
		fos.flush();
		fos.close();
	}

	public void onTaskFinished(DownloadTask task) {

	}

	public void onTaskUpdated(DownloadTask task) {

	}

	public void onTaskError(DownloadTask task, String error) {

	}
}
